#include <vector>
#include <queue>
#include "sched_rr1.h"
#include "basesched.h"
#include <iostream>
#include <string>

using namespace std;
 

SchedRR1::SchedRR1(vector<int> argn) {
// Round robin recibe la cantidad de cores y sus cpu_quantum por parámetro
        quantum = argn.back();
        int i = argn[0];
	cores = i;
        std::vector<int> temp (i);
	std::vector<int> temp2 (i);
	std::vector<int> temp3;
	std::vector<std::queue<int> > cola (cores);

	tareas = cola;
	cpuportareas = temp3;

        for (int j = 0 ; j < i ; j++){
		temp[j] = 0;
		temp2[j] = 0;
		while (!(tareas[j].empty())){
			tareas[j].pop();
		}
        }

        quantumporcpu = temp;
	tareasporcpu = temp2;

        //contQ = 0;
}

SchedRR1::~SchedRR1() {

}

void SchedRR1::load(int pid) {	
	int i = tareasporcpu[0];
	int k = 0;
	int j = 0;
	
	for (j = 0 ; j < cores ; j++){ //veo cual core tiene menos tareas asignadas
        	if(tareasporcpu[j] <= i){
			k = j;
			i = tareasporcpu[j];
		}
        }
	
	j = pid+1;
	cpuportareas.resize(j);
	cpuportareas[j -1] = k;
	tareasporcpu[k]++; //aumento numero de tareas en el cpu
	tareas[k].push(pid);	//agrego tarea al cpu
}

void SchedRR1::unblock(int pid) {
	int c = cpuportareas[pid];
	tareas[c].push(pid);
}

int SchedRR1::tick(int cpu, const enum Motivo m) {
	int res;

		if (m == EXIT) {
        	quantumporcpu[cpu] = 0;
		//	contQ = 0;

			
			if(tareas[cpu].empty()){
				res = IDLE_TASK;
			}
			else{
				res = tareas[cpu].front();
                tareas[cpu].pop();
			}
		}
		else if(m == BLOCK){
			quantumporcpu[cpu] = 0;
	
			if(tareas[cpu].empty()){
				res = IDLE_TASK;
			}
			else{
				res = tareas[cpu].front();
                tareas[cpu].pop();
			}
		}
		else if(m == TICK){
			quantumporcpu[cpu] = quantumporcpu[cpu] + 1; 
			if(quantumporcpu[cpu] == quantum){
				quantumporcpu[cpu] = 0;
                if (tareas[cpu].empty()){
				res = current_pid(cpu);

                }
                else{
            			tareas[cpu].push(current_pid(cpu));
				res = tareas[cpu].front();
				tareas[cpu].pop();

                }
			}
			else{
				if(current_pid(cpu) == IDLE_TASK){
					if(tareas[cpu].empty()){
						quantumporcpu[cpu] = 0;
						res = current_pid(cpu);
					}
					else{
						quantumporcpu[cpu] = 0;
						res = tareas[cpu].front();
				        	tareas[cpu].pop();
					}
				}
				else{
					res = current_pid(cpu);
				}
			}
		}
		else{
			// m == ERROR;
			cerr << "Error"<< endl;
			return -2;
		}

	return res;

}